package yang.VirtualMachine.chapter11.invokedynamic;

import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodHandles.Lookup;
import java.lang.invoke.MethodType;

public class SimpleMethodHandle {
	static class MyPrintln {
		protected void println(String s) {
			System.out.println(s);
		}
	}

	public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, Throwable {
		Object obj = (System.currentTimeMillis() & 1L) == 0L 
				? System.out : new MyPrintln();
		System.out.println(obj.getClass().toString());
		
		getPrintlnMethodHandler(obj).invokeExact("yangxx");
	}
	
	/**
	 * findVirtual 需绑定执行对象
	 * findStatic 静态方法，无需绑定对象实例
	 * findSpecial 私有方法，父类方法（查找的是父类方法，就算绑定本实例，也执行的是父类方法）
	 * findConstructor 构造方法
	 */
	public static MethodHandle getPrintlnMethodHandler(Object receiver) throws NoSuchMethodException, IllegalAccessException {
		// 返回值为void参数为String的方法
		MethodType mt = MethodType.methodType(void.class, String.class);
		
		//用lookup去查找class中方法(class, name, MethodType)
		Lookup lookup = MethodHandles.lookup();
		MethodHandle ret = lookup.findVirtual(receiver.getClass(), "println", mt);
		// 需绑定receiver作为方法调用的指向者
		return ret.bindTo(receiver);
	}
	
	

}
